package com.openxt.nbzj.remoting;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.openxt.nbzj.util.App;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Map;

import qs.openxt.libs.util.SecurityUtil;
import qs.openxt.libs.util.StringUtil;

/**
 * 通过Http方式与IME服务器进行通讯的工具类
 *
 * @author honghao
 */
public class ClientEx {
    private String METHOD_POST = "POST";
    private RemotingEx remotingEx = null;
    private final static String ENCODING = "utf-8";
    public static final String STATUS_OK = "OK";
    public static final String STATUS_ERR = "error";
    public static final String ERR_MESSAGE = "message";
    /***
     * 登录值
     */
    public static String CUSTOMERID = "";
    /***
     * 登录值KEY
     */
    public final static String CUSTOMERID_KEY = "customerid";

    private String serverAddress = "";

    public ClientEx(RemotingEx remotingEx) {
        this.remotingEx = remotingEx;
    }

    public void setServerAddress(String serverAddress) {
        this.serverAddress = serverAddress;
    }

    public void setMethod(String method) {
        METHOD_POST = method;
    }

    public String request(Object args) throws Exception {
        StringBuffer sb = new StringBuffer();
        if (args != null && args instanceof Map) {
            Map<String, String> data = (Map<String, String>) args;
            for (Map.Entry<String, String> entry : data.entrySet()) {
                sb.append(entry.getKey()).append("=").append(URLEncoder.encode(StringUtil.getValue(entry.getValue()), ENCODING)).append("&");
            }
            if (sb.lastIndexOf("&") != -1)
                sb.deleteCharAt(sb.lastIndexOf("&"));
        } else if (args != null)
            sb.append(args);
        long security_timestamp = SecurityUtil.getTimestamp();
        sb.append("&security_timestamp=").append(String.valueOf(security_timestamp));
        String token = SecurityUtil.getToken(App.APPKEY, App.SECRETKEY, security_timestamp);
        sb.append("&security_token=").append(token);

        if ("GET".equalsIgnoreCase(METHOD_POST)) {
            if (serverAddress.lastIndexOf("?") != -1)
                serverAddress += sb.toString();
            else
                serverAddress += "?" + sb.toString();
        }

        URL url = new URL(serverAddress);
        HttpURLConnection connection = null;
        try {
            connection = (HttpURLConnection) url.openConnection();
            if (!StringUtil.isNull(CUSTOMERID)) {
                connection.setRequestProperty(CUSTOMERID_KEY, CUSTOMERID);
            }
            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=" + ENCODING);
            connection.setRequestMethod(METHOD_POST);
            connection.setRequestProperty("Accept-Charset", ENCODING);
            connection.setConnectTimeout(60000);
            connection.setUseCaches(false);
            byte[] req_body = sb.toString().getBytes(ENCODING);
            if ("POST".equalsIgnoreCase(METHOD_POST)) {
                connection.addRequestProperty("Content-length", Integer.toString(req_body.length));
            }
            connection.connect();
            if ("POST".equalsIgnoreCase(METHOD_POST)) {
                OutputStream outputStream = null;
                try {
                    outputStream = connection.getOutputStream();
                    outputStream.write(req_body);
                } finally {
                    if (outputStream != null) {
                        outputStream.close();
                    }
                }
            }
            int status = connection.getResponseCode();
            if (status == 401)
                throw new Exception("会话过期，请重新登录");
            if (status == 500)
                throw new Exception("服务连接失败，请稍候再试");
            InputStream inputStream = null;
            try {
                try {
                    inputStream = connection.getInputStream();
                } catch (Exception ex) {
                    inputStream = connection.getErrorStream();
                }
                if (inputStream == null)
                    return null;

                sb.setLength(0);
                BufferedReader input = new BufferedReader(new InputStreamReader(inputStream));
                String s;
                while ((s = input.readLine()) != null) {
                    sb.append(s);
                }
                input.close();
                if (status == 501) {
                    JSONObject val = JSON.parseObject(sb.toString());
                    throw new Exception(val.getString("Message"));
                } else
                    return sb.toString();
            } finally {
                if (inputStream != null) {
                    inputStream.close();
                }
            }
        } catch (Exception e) {
            if (e instanceof SocketTimeoutException) {
                throw new Exception("连接超时或网络请求失败");
            }
            throw e;
        } finally {
            if (connection != null)
                connection.disconnect();
        }
    }
}
